package com.ziytek.web.citizen.controller;

import com.google.gson.Gson;
import com.ziytek.web.citizen.config.caffeine.CaffeineUtil;
import com.ziytek.web.citizen.constant.ApiConstant;
import com.ziytek.web.citizen.constant.NumConstant;
import com.ziytek.web.citizen.constant.ServerConstant;
import com.ziytek.web.citizen.enums.ResponseEnum;
import com.ziytek.web.citizen.mapper.BoardConfigMapper;
import com.ziytek.web.citizen.model.req.*;
import com.ziytek.web.citizen.model.rsp.*;
import com.ziytek.web.citizen.model.vo.OperationVo;
import com.ziytek.web.citizen.service.*;
import com.ziytek.web.citizen.service.itf.*;
import com.ziytek.web.citizen.util.DateTimeUtils;
import com.ziytek.web.citizen.util.KeyUtil;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 数据查询接口
 *
 * @author fenghx
 * @version 1.0
 * @className QueryDataController
 * @date 2023/12/7 16:41
 **/
@Slf4j
@RestController
@RequestMapping(ApiConstant.API_CABINET)
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class QueryDataController {
    private final Gson gson;
    private final OfflineService offlineService;
    private final BatchNoService batchNoService;
    private final CabinetNoService cabinetNoService;
    private final BoardConfigMapper boardConfigMapper;
    private final StatusQueryService statusQueryService;
    private final StepSettingService stepSettingService;
    private final LocalCapacityService localCapacityService;
    private final CapacityStatusService capacityStatusService;
    private final CapacityDetailService capacityDetailService;
    private final CapacitySchemeService capacitySchemeService;
    private final OperationVoCacheService operationVoCacheService;
    private final SingleBatteryCellService singleBatteryCellService;
    private final ControllerVersionService controllerVersionService;
    private final BatteryDetailsQueryService batteryDetailsQueryService;
    private final BatteryComprehensiveService batteryComprehensiveService;
    private final LastRealtimeDataQueryService lastRealtimeDataQueryService;


    /**
     * 整体工艺方案执行情况查询接口
     *
     * @param request 请求参数
     * @return 整体工艺方案执行情况查询接口响应
     */
    @PostMapping(ApiConstant.WHOLE_STEP_ISSUED_QUERY)
    public WholeStepIssuedQueryRsp wholeStepIssuedQuery(@Valid @RequestBody WholeStepIssuedQueryReq request) {
        //log.info("wholeStepIssuedQuery request parameters:{}", gson.toJson(request));
        var rsp = new WholeStepIssuedQueryRsp();
        var k = CaffeineUtil.CACHE_KEY_COMMAND_OPERATE_ALL + CaffeineUtil.getCacheKey(request.getCabinetNo(), NumConstant.INT_TWO_FIFTY_FIVE, NumConstant.INT_TWO_FIFTY_FIVE);
        Integer timeCount = CaffeineUtil.get(k);
        rsp.success(timeCount != null && timeCount > NumConstant.INT_ZERO);
        return rsp;
    }

    /**
     * 单个电池工艺方案执行情况查询接口
     *
     * @param request 请求参数
     * @return 单个电池工艺方案执行情况查询接口响应
     */
    @PostMapping(ApiConstant.SINGLE_STEP_ISSUED_QUERY)
    public SingeStepIssuedQueryRsp singeStepIssuedQuery(@Valid @RequestBody SingeStepIssuedQueryReq request) {
        //log.info("singeStepIssuedQuery request parameters:{}", gson.toJson(request));
        var rsp = new SingeStepIssuedQueryRsp();
        rsp.success(false);

        var bc = boardConfigMapper.queryByDoorAndChannelNo(request.getDoor(), request.getLineNo(), request.getChannelNo());
        if (bc == null) {
            log.error("singeStepIssuedQuery boardConfig is null");
            return rsp;
        }

        var opKey = KeyUtil.commandOperateKey(request.getCabinetNo(), bc.getAddress(), bc.getChannelNo());
        OperationVo vo = operationVoCacheService.getOperationVo(opKey);
        rsp.success(vo != null && vo.getStartFlag() != ServerConstant.START_FLAG_NORMAL);
        return rsp;
    }


    /**
     * 电池实时数据查询接口(工步执行中首页数据展示数据)
     *
     * @param request 请求参数
     * @return 电池实时数据查询接口响应
     */
    @PostMapping(ApiConstant.LAST_REALTIME_DATA_QUERY)
    public RealtimeDataRsp lastRealtimeDataQuery(@Valid @RequestBody RealtimeDataQueryReq request) {
        //log.info("Real time data query request parameters:{}", gson.toJson(request));
        return lastRealtimeDataQueryService.queryRealData(request);
    }

    /**
     * 每个电芯充放电详情数据查询接口(单个电芯电流电压曲线图)
     *
     * @param request 请求参数
     * @return 每个电芯充放电详情数据查询接口响应
     */
    @PostMapping(ApiConstant.BATTERY_DETAILS_QUERY)
    public BatteryDetailsRsp batteryDetailsQuery(@Valid @RequestBody BatteryDetailsQueryReq request) {
        //log.info("Request parameters for querying current and voltage curve data of battery cells:{}", gson.toJson(request));
        //return batteryDetailsQueryService.batteryDetailsQuery(request);
        // 为空时查询当前工步数据
        if (StringUtils.isBlank(request.getBatchNo())) {
            return batteryDetailsQueryService.batteryDetailsQuery(request);
        }

        BatteryDetailsHistoryQueryReq req = new BatteryDetailsHistoryQueryReq();
        BeanUtils.copyProperties(request, req);
        return batteryDetailsQueryService.batteryDetailsHistoryQuery(req);
    }

    /**
     * 每个电芯充放电详情历史数据查询接口(单个电芯电流电压曲线历史数据查询)
     *
     * @param request 请求参数
     * @return 每个电芯充放电详情数据查询接口响应
     */
    @PostMapping(ApiConstant.BATTERY_HISTORY_DETAILS_QUERY)
    public BatteryDetailsRsp batteryDetailsHistoryQuery(@Valid @RequestBody BatteryDetailsHistoryQueryReq request) {
        log.info("曲线历史数据查询请求batteryDetailsHistoryQuery:{}", gson.toJson(request));
        return batteryDetailsQueryService.batteryDetailsHistoryQuery(request);
    }

    /**
     * 电池综合列表数据查询接口
     *
     * @param request 请求参数
     * @return 电池综合列表数据查询响应
     */
    @PostMapping(ApiConstant.BATTERY_COMPREHENSIVE_LIST_QUERY)
    public BatteryComprehensiveRsp batteryComprehensiveListQuery(@Valid @RequestBody BatteryListQueryReq request) {
        //log.info("Battery comprehensive list data query request parameters:{}", gson.toJson(request));
        return batteryComprehensiveService.batteryComprehensiveListQuery(request);
    }

    /**
     * 电池容量级别统计数据查询接口(已弃用，返回数据为空)
     *
     * @param request 请求参数
     * @return 电池容量级别统计数据查询响应
     */
    @PostMapping(ApiConstant.CAPACITY_STATISTICS_QUERY)
    public CapacityStatisticsQueryRsp capacityStatisticsQuery(@RequestBody CapacityStatisticsQueryReq request) {
        log.info("Capacity level statistical data query request parameters:{}", gson.toJson(request));
        CapacityStatisticsQueryRsp capacityStatisticsQueryRsp = new CapacityStatisticsQueryRsp();
        capacityStatisticsQueryRsp.setRetCode("0");
        capacityStatisticsQueryRsp.setRetMsg("success");
        return capacityStatisticsQueryRsp;
    }

    /**
     * 电池分容容量详情数据查询接口(已弃用，返回数据为空)
     *
     * @param request 请求参数
     * @return 电池容量级别统计数据查询响应
     */
    @PostMapping(ApiConstant.CAPACITY_DETAILS_QUERY)
    public CapacityDetailsQueryRsp capacityDetailsQuery(@RequestBody CapacityDetailsQueryReq request) {
        log.info("Capacity Details Data Query Request Parameters:{}", gson.toJson(request));
        CapacityDetailsQueryRsp capacityDetailsQueryRsp = new CapacityDetailsQueryRsp();
        capacityDetailsQueryRsp.setRetCode("0");
        capacityDetailsQueryRsp.setRetMsg("success");
        return capacityDetailsQueryRsp;
    }


    /***
     * 正在执行的工步指令数据查询接口(已弃用，返回数据为空)
     * @param request 请求参数
     * @return 正在执行的工步指令数据查询响应
     */
    @PostMapping(ApiConstant.EXECUTING_STEP_QUERY)
    public ExecutingStepQueryRsp executingStepQuery(@RequestBody ExecutingStepQueryReq request) {
        ExecutingStepQueryRsp executingStepQueryRsp = new ExecutingStepQueryRsp();
        executingStepQueryRsp.setRetCode("0");
        executingStepQueryRsp.setRetMsg("success");

        return executingStepQueryRsp;
    }


    /**
     * 工步设置方案查询接口
     *
     * @param request 请求参数
     * @return 工步设置方案查询响应
     */
    @PostMapping(ApiConstant.STEP_QUERY)
    public StepSettingsQueryRsp stepQuery(@Valid @RequestBody StepSettingsQueryReq request) {
        log.info("Step setting scheme query request parameters:{}", gson.toJson(request));
        return stepSettingService.stepQuery(request);
    }

    /**
     * 分容设置方案查询接口
     *
     * @param request 请求参数
     * @return 分容设置方案查询响应
     */
    @PostMapping(ApiConstant.SCHEME_QUERY)
    public SchemeQueryRsp schemeQuery(@Valid @RequestBody SchemeQueryReq request) {
        log.info("Query request parameters for capacity setting scheme:{}", gson.toJson(request));
        return capacitySchemeService.schemeQuery(request);
    }

    /**
     * 可下发指令机柜号查询接口
     *
     * @param request 请求参数
     * @return 可下发指令机柜号查询响应
     */
    @PostMapping(ApiConstant.CABINET_NO_QUERY)
    public CabNoQueryRsp cabinetNoQuery(@Valid @RequestBody CabNoQueryReq request) {
        log.info("连接设备查询:{}", gson.toJson(request));
        var rsp = new CabNoQueryRsp();
        rsp.setRetCode(ResponseEnum.SUCCESS.getCode());
        rsp.setRetMsg(ResponseEnum.SUCCESS.getDesc());

        var list = cabinetNoService.ipList();
        if (CollectionUtils.isEmpty(list)) {
            rsp.setRetCode(ResponseEnum.OBJECT_NOT_EXIST.getCode());
            rsp.setRetMsg("未检测到连接设备,请检查设备网络!");
            return rsp;
        }

        rsp.setCabinetNoList(list);
        return rsp;
    }

    /**
     * 离线设备信息查询接口
     *
     * @param request 请求参数
     * @return 离线设备信息查询响应
     */
    @PostMapping(ApiConstant.OFFLINE_DEVICE_QUERY)
    public OfflineQueryRsp offlineQuery(@Valid @RequestBody OfflineQueryReq request) {
        log.info("Offline device information query request parameters:{}", gson.toJson(request));
        var rsp = new OfflineQueryRsp();
        rsp.setRetCode(ResponseEnum.SUCCESS.getCode());
        rsp.setRetMsg(ResponseEnum.SUCCESS.getDesc());
        rsp.setOfflineList(offlineService.offline(request.getToken()));
        return rsp;
    }


    /**
     * 机柜程序版本查询接口
     *
     * @param request 请求参数
     * @return 机柜程序版本查询响应
     */
    @PostMapping(ApiConstant.CABINET_VERSION_QUERY)
    public VersionRsp versionQuery(@Valid @RequestBody VersionReq request) {
        log.info("Cabinet program version query request parameters:{}", gson.toJson(request));
        return controllerVersionService.getVersionInfo(request.getCabinetNo());
    }

    /**
     * 本地设备分容结果查询接口
     *
     * @param request 请求参数
     * @return 本地设备分容结果查询响应
     */
    @PostMapping(ApiConstant.LOCAL_DEVICE_CAPACITY_QUERY)
    public LocalDeviceCapacityRsp localDeviceCapacityQuery(@Valid @RequestBody LocalDeviceCapacityReq request) {
        log.info("Local device capacity partitioning result query request parameters:{}", gson.toJson(request));
        var rsp = new LocalDeviceCapacityRsp();
        rsp.setRetCode(ResponseEnum.SUCCESS.getCode());
        rsp.setRetMsg(ResponseEnum.SUCCESS.getDesc());
        rsp.setData(localCapacityService.localCapacityQueryByCabinetNo(request.getCabinetNo()));
        return rsp;
    }

    /**
     * 历史数据数据库文件查询接口(已弃用，返回数据为空)
     *
     * @param request 请求参数
     * @return 历史数据数据库文件查询响应
     */
    @PostMapping(ApiConstant.HISTORY_DB_NAME_QUERY)
    public QueryDbNameRsp historyDbNameQuery(@RequestBody QueryDbNameReq request) {
        log.info("Historical data database file query request parameters:{}", gson.toJson(request));
        QueryDbNameRsp rsp = new QueryDbNameRsp();
        rsp.setRetCode(ResponseEnum.SUCCESS.getCode());
        rsp.setRetMsg(ResponseEnum.SUCCESS.getDesc());
        return rsp;
    }

    /**
     * 实时曲线单个电芯最后一条电压电流数据查询接口
     *
     * @param request 请求参数
     * @return 实时曲线单个电芯最后一条电压电流数据查询响应
     */
    @PostMapping(ApiConstant.SINGLE_BATTERY_CELL_QUERY)
    public SingleBatteryCellRsp singleBatteryCellQuery(@Valid @RequestBody SingleBatteryCellReq request) {
        log.info("实时曲线单个电芯最后一条电压电流数据查询Real time curve, last voltage and current data query request parameters for a single battery cell:{}", gson.toJson(request));
        return singleBatteryCellService.getSingleBatteryCell(request);
    }

    /**
     * 所有批次号查询接口
     *
     * @param request 请求参数
     * @return 所有批次号查询响应
     */
    @PostMapping(ApiConstant.BATCH_NO_QUERY)
    public BatchNoQueryRsp batchNoQuery(@Valid @RequestBody BatchNoQueryReq request) {
        log.info("batchNoQuery:{}", gson.toJson(request));
        return batchNoService.batchNoQuery(request);
    }

    /**
     * 所有机柜状态查询接口
     *
     * @param request 请求参数
     * @return 所有机柜状态查询响应
     */
    @PostMapping(ApiConstant.STATUS_QUERY)
    public StatusQueryRsp statusQuery(@Valid @RequestBody StatusQueryReq request) {
        log.info("statusQuery:{}", gson.toJson(request));
        return statusQueryService.statusQuery(request);
    }

    /**
     * 电池放电容量数据查询接口
     *
     * @param request 请求参数
     * @return 电池放电容量数据查询响应
     */
    @PostMapping(ApiConstant.CAPACITY_STATUS_QUERY)
    public CapStatusQueryRsp capacityStatusQuery(@Valid @RequestBody CapStatusQueryReq request) {
        log.info("capacityStatusQuery:{}", gson.toJson(request));
        // 当天日期的
        if (StringUtils.isNotBlank(request.getBatchNo()) && DateTimeUtils.isToday(request.getBatchNo())) {
            return capacityStatusService.capacityStatusQuery(request);
        }

        return capacityStatusService.historyCapacityStatusQuery(request);
    }


    /**
     * 电池容量详情数据查询接口
     *
     * @param request 请求参数
     * @return 电池容量详情数据查询响应
     */
    @PostMapping(ApiConstant.CAPACITY_DETAIL_QUERY)
    public CapDetailQueryRsp capDetailQuery(@Valid @RequestBody CapDetailQueryReq request) {
        log.info("capDetailQuery:{}", gson.toJson(request));
        // 当天日期的
        if (StringUtils.isNotBlank(request.getBatchNo()) && DateTimeUtils.isToday(request.getBatchNo())) {
            return capacityDetailService.capDetailQuery(request);
        }
        return capacityDetailService.historyCapDetailQuery(request);
    }
}
